<?php

declare(strict_types=1);

namespace app\common\dao\sys;

use app\common\model\sys\SysDict;
use app\common\traits\DaoTrait;

/**
 * 系统字典 - DAO
 * @author:kaige
 * @update:2022-06-12
 * @copyright ©2022 泉州市盛筑信息科技有限公司 版权所有
 */
class DictDao
{
  // 当前操作的模型
  protected $model = null;

  // 对应模型的主键，默认为id
  protected $pk = 'id';

  // 对应模型默认查询的字段
  protected $name = 'code';

  // 对应模型允许查询的字段(默认全部查询)
  protected $allowField = ['*'];

  // 允许单字段更新
  protected $uaField = ['sort'];

  // 查询结果-要隐藏的字段 默认空数组
  protected $hideField = [];

  public function __construct()
  {
    $this->model = new SysDict();
  }

  use DaoTrait;

  /**
   * 获取字典信息
   * @param int $id
   * @return mixed
   */
  public function getInfo($id = 0)
  {
    if ($id > 0) {
      $data = $this->model->alias('a')->field('a.*,u.real_name as handle_name,c.name as pid_name')
        ->leftjoin('\app\common\model\sys\SysUser u', 'u.id=a.handle_uid')
        ->leftjoin('\app\common\model\sys\SysDict c', 'a.pid = c.id')
        ->where('a.id', $id)
        ->find();
      if (isset($data['handle_time']) && !empty($data['handle_time'])) {
        $data['handle_time'] = time2str($data['handle_time']);
      }
      return $data;
    }
    return false;
  }

  /**
   * 重写_del方法
   * @param mixed $id
   * @return array
   */
  public function _del($id)
  {
    if (!empty($id)) {
      $ids = $this->inSubs($id, true);
      if ($ids) {
        $ids = explode(',', $ids);
        $res = $this->model->where([
          ['is_lock', '<>', 1],
          ['id', 'in', $ids]
        ])->useSoftDelete('delete_time', time())->delete();
        if ($res) {
          return _ok(1025, $ids);
        }
      }
    }
    return _err(1026);
  }

  /**
   * 列出所有子节点
   * @param int $id
   * @param bool $noid 是否包含本id
   * @return string '1,2,3...'
   */
  public function inSubs($id, $noid = false)
  {
    $arr = '';
    if (!empty($id)) {
      $data = $this->getSubId($id);
      foreach ($data as $k => $v) {
        $arr .= $v['id'] . ',';
      }
      if ($noid)
        $arr .= $id;
    }
    return $arr;
  }

  /**
   * 找子节点
   * @param int $id
   * @return array
   */
  public function getSubId($id)
  {
    $data = [];
    $d1 = $this->getListAll();
    if (!$d1) {
      return $data;
    }
    $data = $this->getDictTree($d1, $id, 0);
    return $data;
  }

  /**
   * 递归无限级分类【先序遍历算】，获取任意节点下所有子节点
   * @param array $arrCate 待排序的数组
   * @param int $pid 父级节点
   * @param int $level 层级数
   * @return array $arrTree 排序后的数组
   */
  function getDictTree($arrCat, $pid = 0, $level = 0)
  {
    static $arrTree = array(); //使用static代替global
    if (empty($arrCat)) return [];
    $level++;
    foreach ($arrCat as $key => $value) {
      if ($value['pid'] == $pid) {
        $value['level'] = $level;
        $arrTree[] = $value;
        unset($arrCat[$key]); //注销当前节点数据，减少已无用的遍历
        $this->getDictTree($arrCat, $value['id'], $level);
      }
    }
    return $arrTree;
  }

  /**
   * 获取字典
   * @param $ids 字典大类ID,可以是数组 [1,2]
   * @return array 输出子项 数组如 ['typename'=>[a=>1],'typename2'=>[a=>2]]
   */
  public function getDict($ids)
  {
    $result = [];
    if ($ids) {
      if (!is_array($ids)) {
        $arr = explode(',', $ids);
      } else {
        $arr = $ids;
      }
      foreach ($arr as $v) {
        if (!empty($v)) {
          //取自身，code作为key  
          $data = $this->model->where('id', $v)->find();
          if ($data) {
            $data = $data->toArray();
            $key = $data['code'];
            $subData = $this->model->where('pid', $v)->select();
            $result[$key] = [];
            foreach ($subData as $k1 => $v1) {
              $result[$key][] = [
                'name' => $v1['name'],
                'value' => $v1['value'],
                'explain' => $v1['explain']
              ];
            }
          }
        }
      }
    }
    return $result;
  }

  /**
   * 取出所有字典
   */
  public function getDictAll($company_id = 0)
  {
    $param = [];
    $list = [];
    $list = $this->model->where('company_id', $company_id)->select()->toArray();
    if (count($list) > 0) {
      foreach ($list as $key => $val) {
        if ($val['pid'] == 0) {
          $options = [];
          foreach ($list as $v) {
            if ($v['pid'] == $val['id']) {
              $options[$v['value']] = $v['name'];
            }
          }
          $param[$val['code']] = $options;
        }
      };
    }
    return $param;
  }
}
